package com.wan37.logic.db;

import com.wan37.logic.LogicStarter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * @author : luoyong
 * @date : 2020-07-16 17:06
 **/
@Component
public class AsynDBManager {
    private static final Logger logger = LoggerFactory.getLogger(AsynDBManager.class);

    /**
     * worker数组, 每一个worker代表一个"作业线程"
     */
    private Work[] works;
    /**
     * worker线程的数量
     */
    private int workerNum;

    public AsynDBManager() {
        //初始化works
        this.workerNum = LogicStarter.workerNum;
    }


    /**
     * 启动工作线程
     */
    public void startWorks() {

        this.works = new Work[workerNum];
        for (int i = 0; i < workerNum; i++) {
            this.works[i] = new Work();
            //启动对应的worker线程
            new Thread(this.works[i]).start();
        }
        logger.info("Works create success.");
    }


    /**
     * 分发消息给Work线程进行处理.
     *
     * @param workId   -- 传入的id
     * @param runnable -- 对应线程
     */
    public void distributeWork(String workId, Runnable runnable) {

        //首先计算workerIndex
        int workerIndex = getWorkIndex(workId);
        if (runnable == null) {
            logger.info("runnable is null.");
            return;
        }
        //找到对应的worker, 添加msgHandler
        Work work = this.works[workerIndex];
        work.addTask(runnable);
    }


    /**
     * 根据userId计算workerIndex的值.
     * 因为worker的数量是有限的, 为了分配处理用户认证请求的worker, 需要进行简单的转换.
     *
     * @param workId
     * @return
     */
    private int getWorkIndex(String workId) {

        //注意：和0x7FFFFFFF与, 是为了保证最后的结果为正值
        return (workId.hashCode() & 0x7FFFFFFF) % this.workerNum;
    }
}
